package cn.lingyangwl.agile.plugin.file.preview.service.impl;

import cn.lingyangwl.framework.core.response.Resp;
import cn.lingyangwl.framework.core.response.RetOps;
import cn.lingyangwl.framework.tool.core.exception.BizException;
import cn.lingyangwl.agile.plugin.file.preview.config.ConfigConstants;
import cn.lingyangwl.agile.plugin.file.preview.config.FileErrorEnum;
import cn.lingyangwl.agile.plugin.file.preview.filter.BaseUrlFilter;
import cn.lingyangwl.agile.plugin.file.preview.model.FileAttribute;
import cn.lingyangwl.agile.plugin.file.preview.model.FilePreviewRS;
import cn.lingyangwl.agile.plugin.file.preview.model.FileType;
import cn.lingyangwl.agile.plugin.file.preview.service.FileHandlerService;
import cn.lingyangwl.agile.plugin.file.preview.service.FilePreview;
import cn.lingyangwl.agile.plugin.file.preview.utils.DownloadUtils;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;

/**
 * @author shenguangyang
 * @since 1.0.0
 */
@Service
public class MediaFilePreviewImpl implements FilePreview {

    private final FileHandlerService fileHandlerService;
    private final OtherFilePreviewImpl otherFilePreview;

    private static final Object LOCK=new Object();

    public MediaFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
        this.fileHandlerService = fileHandlerService;
        this.otherFilePreview = otherFilePreview;
    }

    @Override
    public FilePreviewRS filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
        // 不是http开头，浏览器不能直接访问，需下载到本地
        if (url != null && !url.toLowerCase().startsWith("http")) {
            Resp<String> response = DownloadUtils.downLoad(fileAttribute, fileAttribute.getName());
            if (!RetOps.of(response).isSuccess()) {
                throw new BizException(response.getMsg());
            } else {
                url= BaseUrlFilter.getBaseUrl() + fileHandlerService.getRelativePath(response.getData());
                fileAttribute.setUrl(url);
            }
        }

        if(checkNeedConvert(fileAttribute.getSuffix())){
            url=convertUrl(fileAttribute);
        }else{
            //正常media类型
            String[] medias = ConfigConstants.getMedia();
            for(String media:medias){
                if(media.equals(fileAttribute.getSuffix())){
                    model.addAttribute("mediaUrl", url);
                    return FilePreviewRS.builder().type(MEDIA_FILE_PREVIEW_PAGE).build();
                }
            }
            throw new BizException(FileErrorEnum.FILE_NOT_SUPPORTED);
        }
        model.addAttribute("mediaUrl", url);
        return FilePreviewRS.builder().type(MEDIA_FILE_PREVIEW_PAGE).build();
    }

    /**
     * 检查视频文件处理逻辑
     * 返回处理过后的url
     * @return url
     */
    private String convertUrl(FileAttribute fileAttribute) {
        String url = fileAttribute.getUrl();
        if(fileHandlerService.listConvertedMedias().containsKey(url)){
            url= fileHandlerService.getConvertedMedias(url);
        }else{
            if(!fileHandlerService.listConvertedMedias().containsKey(url)){
                synchronized(LOCK){
                    if(!fileHandlerService.listConvertedMedias().containsKey(url)){
                        String convertedUrl=convertToMp4(fileAttribute);
                        //加入缓存
                        fileHandlerService.addConvertedMedias(url,convertedUrl);
                        url=convertedUrl;
                    }
                }
            }
        }
        return url;
    }

    /**
     * 检查视频文件转换是否已开启，以及当前文件是否需要转换
     */
    private boolean checkNeedConvert(String suffix) {
        //1.检查开关是否开启
        if("false".equals(ConfigConstants.getMediaConvertDisable())){
            return false;
        }
        //2.检查当前文件是否需要转换
        String[] mediaTypesConvert = FileType.MEDIA_TYPES_CONVERT;
        String type = suffix;
        for(String temp : mediaTypesConvert){
            if(type.equals(temp)){
                return true;
            }
        }
        return false;
    }

    /**
     * 将浏览器不兼容视频格式转换成MP4
     */
    private static String convertToMp4(FileAttribute fileAttribute) {

//        //说明：这里做临时处理，取上传文件的目录
//        String homePath = ConfigUtils.getHomePath();
//        String filePath = homePath+File.separator+"file"+File.separator+"demo"+File.separator+fileAttribute.getName();
//        String convertFileName=fileAttribute.getUrl().replace(fileAttribute.getSuffix(),"mp4");
//
//        File file=new File(filePath);
//        FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file);
//        String fileName = null;
//        Frame captured_frame = null;
//        FFmpegFrameRecorder recorder = null;
//        try {
//            fileName = file.getAbsolutePath().replace(fileAttribute.getSuffix(),"mp4");
//            File desFile=new File(fileName);
//            //判断一下防止穿透缓存
//            if(desFile.exists()){
//                return fileName;
//            }
//
//            frameGrabber.start();
//            recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
//            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); //avcodec.AV_CODEC_ID_H264  //AV_CODEC_ID_MPEG4
//            recorder.setFormat("mp4");
//            recorder.setFrameRate(frameGrabber.getFrameRate());
//            //recorder.setSampleFormat(frameGrabber.getSampleFormat()); //
//            recorder.setSampleRate(frameGrabber.getSampleRate());
//
//            recorder.setAudioChannels(frameGrabber.getAudioChannels());
//            recorder.setFrameRate(frameGrabber.getFrameRate());
//            recorder.start();
//            while ((captured_frame = frameGrabber.grabFrame()) != null) {
//                try {
//                    recorder.setTimestamp(frameGrabber.getTimestamp());
//                    recorder.record(captured_frame);
//                } catch (Exception e) {
//                }
//            }
//            recorder.stop();
//            recorder.release();
//            frameGrabber.stop();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        //是否删除源文件
//        //file.delete();
//        return convertFileName;
        return null;
    }
}
